home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / proc / procID.c < prev    next >
C/C++ Source or Header  |  1990-09-12  |  9KB  |  346 lines

  1. /*
  2.  *  procID.c --
  3.  *
  4.  *    Routines to get and set the various identifiers of a process.
  5.  *    The routines implement the system calls of the same name. 
  6.  *    Synchronization to process table entries is done by locking the
  7.  *    process's PCB.
  8.  *
  9.  * Copyright (C) 1986, 1988 Regents of the University of California
  10.  * Permission to use, copy, modify, and distribute this
  11.  * software and its documentation for any purpose and without
  12.  * fee is hereby granted, provided that the above copyright
  13.  * notice appear in all copies.  The University of California
  14.  * makes no representations about the suitability of this
  15.  * software for any purpose.  It is provided "as is" without
  16.  * express or implied warranty.
  17.  */
  18.  
  19. #ifndef lint
  20. static char rcsid[] = "$Header: /sprite/src/kernel/proc/RCS/procID.c,v 9.3 90/09/12 13:57:58 jhh Exp $ SPRITE (Berkeley)";
  21. #endif /* not lint */
  22.  
  23. #include <sprite.h>
  24. #include <proc.h>
  25. #include <stdlib.h>
  26. #include <status.h>
  27. #include <sync.h>
  28. #include <sched.h>
  29. #include <vm.h>
  30. #include <bstring.h>
  31.  
  32. /*
  33.  * Define a macro to get the minimum of two values.  Note: it is *not*
  34.  * side-effect free.  If "a" or "b" is a function call, the function will
  35.  * be called twice.  Of course, there shouldn't be side-effects in
  36.  * conditional expressions.
  37.  */
  38.  
  39. #define Min(a,b) ((a) < (b) ? (a) : (b))
  40.  
  41.  
  42. /*
  43.  *----------------------------------------------------------------------
  44.  *
  45.  * Proc_GetIDs --
  46.  *
  47.  *    Returns the process ID, user ID and effective user ID of the current
  48.  *    process.
  49.  *
  50.  * Results:
  51.  *    SYS_ARG_NOACCESS -     the arguments were not accessible.
  52.  *    PROC_INVALID_PID -    the pid argument was illegal.
  53.  *
  54.  * Side effects:
  55.  *    None.
  56.  *
  57.  *----------------------------------------------------------------------
  58.  */
  59.  
  60. ReturnStatus
  61. Proc_GetIDs(procIDPtr, parentIDPtr, userIDPtr, effUserIDPtr)
  62.     Proc_PID     *procIDPtr;    /* Where to return pid. */
  63.     Proc_PID     *parentIDPtr;    /* Where to return parent's pid */
  64.     int     *userIDPtr;    /* Where to return real user id. */
  65.     int     *effUserIDPtr;    /* Where to return effective user id. */
  66. {
  67.     register Proc_ControlBlock     *procPtr;
  68.     Proc_PID myPID;
  69.  
  70.     procPtr = Proc_GetEffectiveProc();
  71.  
  72.     /*
  73.      *  Copy the information to the out parameters.
  74.      */
  75.  
  76.     if (procIDPtr != USER_NIL) {
  77.     /*
  78.      * Return the process ID this process thinks it is, not necessarily
  79.      * the one in the PCB.
  80.      */
  81.     if (procPtr->genFlags & PROC_FOREIGN) {
  82.         myPID = procPtr->peerProcessID;
  83.     } else {
  84.         myPID = procPtr->processID;
  85.     }
  86.     if (Proc_ByteCopy(FALSE, sizeof(Proc_PID), 
  87.         (Address) &myPID, (Address) procIDPtr) != SUCCESS) {
  88.         return(SYS_ARG_NOACCESS);
  89.     }
  90.     }
  91.  
  92.     if (parentIDPtr != USER_NIL) {
  93.     if (Proc_ByteCopy(FALSE, sizeof(Proc_PID), 
  94.         (Address) &(procPtr->parentID), (Address) parentIDPtr) != SUCCESS){
  95.         return(SYS_ARG_NOACCESS);
  96.     }
  97.     }
  98.  
  99.     if (userIDPtr != USER_NIL) {
  100.     if (Proc_ByteCopy(FALSE, sizeof(int), 
  101.         (Address) &(procPtr->userID), (Address) userIDPtr) != SUCCESS){
  102.         return(SYS_ARG_NOACCESS);
  103.     }
  104.     }
  105.  
  106.     if (effUserIDPtr != USER_NIL) {
  107.     if (Proc_ByteCopy(FALSE, sizeof(int), 
  108.         (Address) &(procPtr->effectiveUserID), 
  109.         (Address) effUserIDPtr) != SUCCESS){
  110.         return(SYS_ARG_NOACCESS);
  111.     }
  112.     }
  113.     return(SUCCESS);
  114. }
  115.  
  116.  
  117. /*
  118.  *----------------------------------------------------------------------
  119.  *
  120.  * Proc_SetIDs --
  121.  *
  122.  *    Changes the user ID or current user ID for the current process.
  123.  *      If an argument is USER_NIL, the corresponding value in
  124.  *    the PCB structure is not changed.
  125.  *
  126.  * Results:
  127.  *    SYS_ARG_NOACCESS -     the arguments were not accessible.
  128.  *    PROC_INVALID_PID -    the pid argument was illegal.
  129.  *
  130.  * Side effects:
  131.  *    The user ID and/or effective user ID for a process may change.
  132.  *
  133.  *----------------------------------------------------------------------
  134.  */
  135.  
  136. ReturnStatus
  137. Proc_SetIDs(userID, effUserID)
  138.     int     userID;
  139.     int     effUserID;
  140. {
  141.     register    Proc_ControlBlock     *procPtr;
  142.  
  143.     procPtr = Proc_GetEffectiveProc();
  144.  
  145.     if (userID == PROC_NO_ID) {
  146.     userID = procPtr->userID;;
  147.     }
  148.     if (effUserID == PROC_NO_ID) {
  149.     effUserID = procPtr->effectiveUserID;
  150.     }
  151.     if (userID != procPtr->userID && userID != procPtr->effectiveUserID &&
  152.     procPtr->effectiveUserID != PROC_SUPER_USER_ID) {
  153.        return(PROC_UID_MISMATCH);
  154.     }
  155.     if (effUserID != procPtr->userID && effUserID != procPtr->effectiveUserID &&
  156.     procPtr->effectiveUserID != PROC_SUPER_USER_ID) {
  157.        return(PROC_UID_MISMATCH);
  158.     }
  159.     procPtr->userID = userID;
  160.     procPtr->effectiveUserID = effUserID;
  161.  
  162.     if (procPtr->state == PROC_MIGRATED) {
  163.     return(Proc_MigUpdateInfo(procPtr));
  164.     }
  165.     return(SUCCESS);
  166. }
  167.  
  168.  
  169. /*
  170.  *----------------------------------------------------------------------
  171.  *
  172.  * Proc_GetGroupIDs --
  173.  *
  174.  *    Returns all the group IDs of a process if the gidArrayPtr
  175.  *    argument is not USER_NIL. Also returns the actual number of
  176.  *    groups IDs in the process's PCB structure if trueNumGidsPtr
  177.  *    is not USER_NIL.
  178.  *
  179.  *    TODO: Move me to fs.
  180.  *
  181.  * Results:
  182.  *    SYS_ARG_NOACCESS -     the arguments were not accessible.
  183.  *    SYS_INVALID_ARG -     the argument was was invalid.
  184.  *    PROC_INVALID_PID -    the pid argument was illegal.
  185.  *    The group IDs are returned.
  186.  *
  187.  * Side effects:
  188.  *    None.
  189.  *
  190.  *----------------------------------------------------------------------
  191.  */
  192.  
  193. ReturnStatus
  194. Proc_GetGroupIDs(numGIDs, gidArrayPtr, trueNumGIDsPtr)
  195.     int        numGIDs;        /* Number of group ids in gidArrayPtr.*/
  196.     int        *gidArrayPtr;        /* Array of group ids. */
  197.     int        *trueNumGIDsPtr;    /* Number of group ids actually 
  198.                      * returned. */
  199. {
  200.     register    Fs_ProcessState     *fsPtr;
  201.     int                 trueNumGIDs;
  202.  
  203.     fsPtr = (Proc_GetEffectiveProc())->fsPtr;
  204.  
  205.     if (numGIDs < 0) {
  206.     return(SYS_INVALID_ARG);
  207.     }
  208.     trueNumGIDs = Min(numGIDs, fsPtr->numGroupIDs);
  209.     if (trueNumGIDs > 0 && gidArrayPtr != USER_NIL) {
  210.     if (Proc_ByteCopy(FALSE, trueNumGIDs * sizeof(int),
  211.               (Address) fsPtr->groupIDs,
  212.               (Address) gidArrayPtr) != SUCCESS) {
  213.         return(SYS_ARG_NOACCESS);
  214.     }
  215.     }
  216.  
  217.     if (trueNumGIDsPtr != USER_NIL) {
  218.     if (Proc_ByteCopy(FALSE, sizeof(int), (Address) &fsPtr->numGroupIDs,
  219.               (Address) trueNumGIDsPtr) != SUCCESS) {
  220.         return(SYS_ARG_NOACCESS);
  221.     }
  222.     }
  223.     return(SUCCESS);
  224. }
  225.  
  226.  
  227. /*
  228.  *----------------------------------------------------------------------
  229.  *
  230.  * Proc_SetGroupIDs --
  231.  *
  232.  *    Changes all the group IDs for a process.
  233.  *
  234.  * Results:
  235.  *    SYS_ARG_NOACCESS -     the argument was not accessible.
  236.  *    SYS_INVALID_ARG -     the argument was was invalid.
  237.  *    PROC_INVALID_PID -    the pid argument was illegal.
  238.  *
  239.  * Side effects:
  240.  *    The process's group IDs are changed.
  241.  *
  242.  *----------------------------------------------------------------------
  243.  */
  244.  
  245. ReturnStatus
  246. Proc_SetGroupIDs(numGIDs, gidArrayPtr)
  247.     int        numGIDs;    /* Number of group ids in gidArrayPtr. */
  248.     int        *gidArrayPtr;    /* Array of group ids. */
  249. {
  250.     register    Proc_ControlBlock    *procPtr;
  251.     register    Fs_ProcessState        *fsPtr;
  252.     int                 *newGidArrayPtr;
  253.     int                 size;
  254.     int                    i;
  255.  
  256.     /*
  257.      * See if there's anything to do before we validate the
  258.      * other arguments.
  259.      */
  260.  
  261.     if ((numGIDs <= 0)  ||  (numGIDs > 128) || (gidArrayPtr == USER_NIL)) {
  262.     return(SYS_INVALID_ARG);
  263.     }
  264.  
  265.     /*
  266.      * Need to protect against abritrary group setting.
  267.      */
  268.     procPtr = Proc_GetEffectiveProc();
  269.     if (procPtr->effectiveUserID != 0) {
  270.     return(GEN_NO_PERMISSION);
  271.     }
  272.  
  273.     Vm_MakeAccessible(VM_READONLY_ACCESS,
  274.             numGIDs * sizeof(int), (Address) gidArrayPtr,
  275.             &size, (Address *) &newGidArrayPtr);
  276.     if (size != (numGIDs * sizeof(int))) {
  277.     return(SYS_ARG_NOACCESS);
  278.     }
  279.  
  280.     /*
  281.      *  If the current group ID table is too small, allocate space
  282.      *    for a larger one.
  283.      */
  284.  
  285.     fsPtr = procPtr->fsPtr;
  286.     if (fsPtr->numGroupIDs < numGIDs) {
  287.     free((Address) fsPtr->groupIDs);
  288.     fsPtr->groupIDs = (int *) malloc(numGIDs * sizeof(int));
  289.     }
  290.  
  291.     for (i=0; i < numGIDs; i++) {
  292.     fsPtr->groupIDs[i] = newGidArrayPtr[i];
  293.     }
  294.     fsPtr->numGroupIDs = numGIDs;
  295.  
  296.     Vm_MakeUnaccessible((Address) newGidArrayPtr, size);
  297.  
  298.     return(SUCCESS);
  299. }
  300.  
  301.  
  302. /*
  303.  *----------------------------------------------------------------------
  304.  *
  305.  * ProcAddToGroupList --
  306.  *
  307.  *    Add the given group ID to the given processes list of groups.
  308.  *
  309.  * Results:
  310.  *    None.
  311.  *
  312.  * Side effects:
  313.  *    A new group is added to the process's group if not already there.
  314.  *
  315.  *----------------------------------------------------------------------
  316.  */
  317. void
  318. ProcAddToGroupList(procPtr, gid)
  319.     Proc_ControlBlock    *procPtr;
  320.     int            gid;
  321. {
  322.     register    Fs_ProcessState *fsPtr = procPtr->fsPtr;
  323.     int     *newGidArrayPtr;
  324.     int        i;
  325.  
  326.     /*
  327.      * See if this gid is already in the list.
  328.      */
  329.     for (i = 0; i < fsPtr->numGroupIDs; i++) {
  330.     if (gid == fsPtr->groupIDs[i]) {
  331.         return;
  332.     }
  333.     }
  334.  
  335.     /*
  336.      * Have to add the new group ID to the list.
  337.      */
  338.     newGidArrayPtr = (int *)malloc((fsPtr->numGroupIDs + 1) * sizeof(int));
  339.     bcopy((Address)fsPtr->groupIDs, (Address)newGidArrayPtr,
  340.         sizeof (int) * fsPtr->numGroupIDs);
  341.     free((Address)fsPtr->groupIDs);
  342.     fsPtr->groupIDs = newGidArrayPtr;
  343.     fsPtr->groupIDs[fsPtr->numGroupIDs] = gid;
  344.     fsPtr->numGroupIDs++;
  345. }
  346.